﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChineseChessStepName
{
    /// <summary>
    /// 棋步名称
    /// </summary>
    public static class StepName
    {
        private const char 俥 = 'R';
        private const char 車 = 'r';
        private const char 傌 = 'N';
        private const char 馬 = 'n';
        private const char 相 = 'B';
        private const char 象 = 'b';
        private const char 仕 = 'A';
        private const char 士 = 'a';
        private const char 帥 = 'K';
        private const char 將 = 'k';
        private const char 炮 = 'C';
        private const char 砲 = 'c';
        private const char 兵 = 'P';
        private const char 卒 = 'p';

        /// <summary>
        /// 棋子名称
        /// </summary>
        private static readonly Dictionary<char, string> PieceName = new()
        {
            { 車, "車" },
            { 俥, "俥" },
            { 馬, "馬" },
            { 傌, "傌" },
            { 相, "相" },
            { 象, "象" },
            { 仕, "仕" },
            { 士, "士" },
            { 將, "將" },
            { 帥, "帥" },
            { 砲, "砲" },
            { 炮, "炮" },
            { 卒, "卒" },
            { 兵, "兵" }
        };

        /// <summary>
        /// 红黑双方军力线路
        /// </summary>
        private const string RedNumber = "一二三四五六七八九";
        private const string BlackNumber = "123456789";

        /// <summary>
        /// 10行
        /// </summary>
        private const int row = 10;
        /// <summary>
        /// 9列
        /// </summary>
        //private const int col = 9;

        /// <summary>
        /// 判断棋子颜色
        /// </summary>
        /// <param name="piece"></param>
        /// <returns></returns>
        private static PieceColor GetPieceColor(char piece)
        {
            if (piece >= 'a' && piece <= 'z')
            {
                return PieceColor.Black;
            }
            else if (piece >= 'A' && piece <= 'Z')
            {
                return PieceColor.Red;
            }
            else
            {
                return PieceColor.White;
            }
        }

        /// <summary>
        /// 棋子颜色
        /// </summary>
        private enum PieceColor
        {
            /// <summary>
            /// 空
            /// </summary>
            White,
            /// <summary>
            /// 红
            /// </summary>
            Red,
            /// <summary>
            /// 黑
            /// </summary>
            Black
        }

        /// <summary>
        /// 移动棋子的棋步名称
        /// 默认已经判断此次移动是合法的
        /// </summary>
        /// <param name="board"></param>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <param name="x2"></param>
        /// <param name="y2"></param>
        /// <returns></returns>
        public static string MoveName(char[,] board, int x1, int y1, int x2, int y2)
        {
            StringBuilder builder = new (PreviourName(board, x1, y1));
            builder.Append(PieceName[board[x1, y1]]);

            //红方棋子
            if (GetPieceColor(board[x1, y1]) == PieceColor.Red)
            {
                builder.Append(RedNumber[8 - y1]);
                //分为直线棋子和斜线棋子
                switch (board[x1, y1])
                {
                    case 俥:
                    case 炮:
                    case 兵:
                    case 帥:
                        if (x1 == x2)
                        {
                            builder.Append('平');
                            builder.Append(RedNumber[8 - y2]);
                        }
                        else if (x1 < x2)
                        {
                            builder.Append('退');
                            builder.Append(RedNumber[x2 - x1 - 1]);
                        }
                        else
                        {
                            builder.Append('进');
                            builder.Append(RedNumber[x1 - x2 - 1]);
                        }
                        break;
                    case 傌:
                    case 相:
                    case 仕:
                        if (x1 < x2)
                        {
                            builder.Append('退');
                        }
                        else
                        {
                            builder.Append('进');
                        }
                        builder.Append(RedNumber[8 - y2]);
                        break;
                }
            }
            //黑方棋子
            else
            {
                builder.Append(BlackNumber[y1]);
                switch (board[x1, y1])
                {
                    case 車:
                    case 砲:
                    case 卒:
                    case 將:
                        if (x1 == x2)
                        {
                            builder.Append('平');
                            builder.Append(BlackNumber[y2]);
                        }
                        else if (x1 > x2)
                        {
                            builder.Append('退');
                            builder.Append(BlackNumber[x2 - x1 - 1]);
                        }
                        else
                        {
                            builder.Append('进');
                            builder.Append(BlackNumber[x1 - x2 - 1]);
                        }
                        break;
                    case 馬:
                    case 象:
                    case 士:
                        if (x1 > x2)
                        {
                            builder.Append('退');
                        }
                        else
                        {
                            builder.Append('进');
                        }
                        builder.Append(BlackNumber[y2]);
                        break;
                }
            }
            return builder.ToString();
        }

        /// <summary>
        /// 棋步的前面名称
        /// </summary>
        /// <param name="board"></param>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <returns></returns>
        private static string PreviourName(char[,] board, int x1, int y1)
        {
            //前面有几个相同类型棋子，后面有几个相同类型棋子
            int before = 0, behind = 0;
            for (int i = 0, j = y1; i < row; i++)
            {
                if (i == x1)
                {
                    continue;
                }
                if (board[i, j] == board[x1, y1])
                {
                    if (i < x1)
                    {
                        if (GetPieceColor(board[x1, y1]) == PieceColor.Red)
                        {
                            before++;
                        }
                        else
                        {
                            behind++;
                        }
                    }
                    else
                    {
                        if (GetPieceColor(board[x1, y1]) == PieceColor.Red)
                        {
                            behind++;
                        }
                        else
                        {
                            before++;
                        }
                    }
                }
            }

            if (behind == 0 && before == 0)
            {
                return "";
            }
            else if (behind == 0)
            {
                return "后";
            }
            else if (before == 0)
            {
                return "前";
            }
            else if (before == behind)
            {
                return "中";
            }
            else
            {
                if (GetPieceColor(board[x1, y1]) == PieceColor.Red)
                {
                    return RedNumber[before].ToString();
                }
                else
                {
                    return BlackNumber[before].ToString();
                }
            }
        }
    }


}
